<?php
/**
 * Created by PhpStorm.
 * User: maskerj
 * Date: 2017/8/24
 * Time: 下午4:15
 * 服务器数据转换成接口
 */

class ServerInfoTrans {
    private $ipv6_conf = "/Users/maskerj/Desktop/npd6.conf";
    private $vpn_status_log = "/Users/maskerj/Desktop/openvpn-status.log";

    /**
     * linux 系统状态探测
     */
    private function sys_linux()
    {
        // CPU
        if (false === ($str = @file("/proc/cpuinfo"))) return false;
        $str = implode("", $str);
        @preg_match_all("/model\s+name\s{0,}\:+\s{0,}([\w\s\)\(\@.-]+)([\r\n]+)/s", $str, $model);
        @preg_match_all("/cpu\s+MHz\s{0,}\:+\s{0,}([\d\.]+)[\r\n]+/", $str, $mhz);
        @preg_match_all("/cache\s+size\s{0,}\:+\s{0,}([\d\.]+\s{0,}[A-Z]+[\r\n]+)/", $str, $cache);
        @preg_match_all("/bogomips\s{0,}\:+\s{0,}([\d\.]+)[\r\n]+/", $str, $bogomips);
        if (false !== is_array($model[1]))
        {
            $res['cpu']['num'] = sizeof($model[1]);
            /*
            for($i = 0; $i < $res['cpu']['num']; $i++)
            {
                $res['cpu']['model'][] = $model[1][$i].'&nbsp;('.$mhz[1][$i].')';
                $res['cpu']['mhz'][] = $mhz[1][$i];
                $res['cpu']['cache'][] = $cache[1][$i];
                $res['cpu']['bogomips'][] = $bogomips[1][$i];
            }*/
            if($res['cpu']['num']==1)
                $x1 = '';
            else
                $x1 = ' ×'.$res['cpu']['num'];
            $mhz[1][0] = ' | 频率:'.$mhz[1][0];
            $cache[1][0] = ' | 二级缓存:'.$cache[1][0];
            $bogomips[1][0] = ' | Bogomips:'.$bogomips[1][0];
            $res['cpu']['model'][] = $model[1][0].$mhz[1][0].$cache[1][0].$bogomips[1][0].$x1;
        }

        // NETWORK

        // UPTIME
        if (false === ($str = @file("/proc/uptime"))) return false;
        $str = explode(" ", implode("", $str));
        $str = trim($str[0]);
        $min = $str / 60;
        $hours = $min / 60;
        $days = floor($hours / 24);
        $hours = floor($hours - ($days * 24));
        $min = floor($min - ($days * 60 * 24) - ($hours * 60));
        if ($days !== 0) $res['uptime'] = $days."天";
        if ($hours !== 0) $res['uptime'] .= $hours."小时";
        $res['uptime'] .= $min."分钟";

        // MEMORY
        if (false === ($str = @file("/proc/meminfo"))) return false;
        $str = implode("", $str);
        preg_match_all("/MemTotal\s{0,}\:+\s{0,}([\d\.]+).+?MemFree\s{0,}\:+\s{0,}([\d\.]+).+?Cached\s{0,}\:+\s{0,}([\d\.]+).+?SwapTotal\s{0,}\:+\s{0,}([\d\.]+).+?SwapFree\s{0,}\:+\s{0,}([\d\.]+)/s", $str, $buf);
        preg_match_all("/Buffers\s{0,}\:+\s{0,}([\d\.]+)/s", $str, $buffers);

        $res['memTotal'] = round($buf[1][0]/1024, 2);
        $res['memFree'] = round($buf[2][0]/1024, 2);
        $res['memBuffers'] = round($buffers[1][0]/1024, 2);
        $res['memCached'] = round($buf[3][0]/1024, 2);
        $res['memUsed'] = $res['memTotal']-$res['memFree'];
        $res['memPercent'] = (floatval($res['memTotal'])!=0)?round($res['memUsed']/$res['memTotal']*100,2):0;

        $res['memRealUsed'] = $res['memTotal'] - $res['memFree'] - $res['memCached'] - $res['memBuffers']; //真实内存使用
        $res['memRealFree'] = $res['memTotal'] - $res['memRealUsed']; //真实空闲
        $res['memRealPercent'] = (floatval($res['memTotal'])!=0)?round($res['memRealUsed']/$res['memTotal']*100,2):0; //真实内存使用率

        $res['memCachedPercent'] = (floatval($res['memCached'])!=0)?round($res['memCached']/$res['memTotal']*100,2):0; //Cached内存使用率

        $res['swapTotal'] = round($buf[4][0]/1024, 2);
        $res['swapFree'] = round($buf[5][0]/1024, 2);
        $res['swapUsed'] = round($res['swapTotal']-$res['swapFree'], 2);
        $res['swapPercent'] = (floatval($res['swapTotal'])!=0)?round($res['swapUsed']/$res['swapTotal']*100,2):0;

        // LOAD AVG
        if (false === ($str = @file("/proc/loadavg"))) return false;
        $str = explode(" ", implode("", $str));
        $str = array_chunk($str, 4);
        $res['loadAvg'] = implode(" ", $str[0]);

        return $res;
    }

    /**
     * 读取openvpn 配置文件信息获取ipv6 prefix
     * @return string
     */
    public function getIPv6Prefix(){
        //读取第六行的Ipv6前缀信息
        $confFile = fopen($this->ipv6_conf,"r") or die("文件不存在");
        $line = 0;
        while ($line <= 5){
            $prefix = fgets($confFile);
            $line++;
        }
        fclose($confFile);
        return str_replace("prefix=",'',trim($prefix));

    }


    /**
     * 获取openvpn 版本信息
     * @return array
     */
    public function getVpnVersion(){
        exec("openvpn --version", $res);
        $vpnVer = $res[0];
        $libVer = $res[1];
        return [
            'vpnVersion'    =>  $vpnVer,
            'libVersion'    =>  $libVer
        ];
    }

    /**
     * 获取 授权数量
     */
    public function getAuthNum(){
        exec("route -A inet6|grep UG|grep tap0|wc -ln", $res);
        return $res[0];
    }

    /**
     * 获取 授权网段信息
     * @return array
     */
    public function getAuthNet(){
        exec("route -A inet6|grep UG|grep tap0", $res);
        return $res;
    }

    /**
     * 统计在线状态
     * @return array
     */
    public function getOnlineInfo(){
        ini_set('date.timezone','Asia/Chongqing');
        $logFile = fopen($this->vpn_status_log,"r");
        //获取第一个数组信息,跳过3行
        fgets($logFile);
        fgets($logFile);
        fgets($logFile);
        $firstArr = [];
        while (($infoStr = trim(fgets($logFile))) != "ROUTING TABLE"){
            $infoArr = explode(",",$infoStr);
            array_push($firstArr,[
                'common_name'   =>  $infoArr[0],
                'real_address'  =>  $infoArr[1],
                'bytes_received'=>  $infoArr[2],
                'bytes_sent'    =>  $infoArr[3],
                'connected_since'=> $infoArr[4]
            ]);
        }
        //跳过一行
        fgets($logFile);
        $secArr = [];
        while (($infoStr = trim(fgets($logFile))) != "GLOBAL STATS"){
            $infoArr = explode(",",$infoStr);
            array_push($secArr,[
                'mac'           =>  $infoArr[0],
                'common_name'   =>  $infoArr[1],
                'real_address'  =>  $infoArr[2],
                'last_ref'      =>  $infoArr[3]
            ]);
        }
        $onlineInfo = [];
        foreach ($firstArr as $item){
            foreach ($secArr as $secOne) {
                if($secOne['real_address'] == $item['real_address']){
                    array_push($onlineInfo,[
                        'mac'   =>  $secOne['mac'],
                        'real_address'  =>  $secOne['real_address'],
                        'bytes_received'=>  ceil($item['bytes_received'] / 1024),
                        'bytes_sent'    =>  ceil($item['bytes_sent'] / 1024),
                        'connected_since'=> date("Y-m-d H:i:s",strtotime($item['connected_since'])),
                        'last_ref'      =>  date("Y-m-d H:i:s",strtotime($secOne['last_ref'])),
                        'online_time'   =>  strtotime($secOne['last_ref']) - strtotime($item['connected_since'])
                    ]);
                }
            }
        }
        fclose($logFile);

        return $onlineInfo;
    }

    /**
     * 获取 服务器参数
     * @return array
     */
    public function getSysParam(){
        $sysInfo = $this->sys_linux();
        $serverName = $_SERVER['SERVER_NAME'];
        if('/'==DIRECTORY_SEPARATOR){$ip = $_SERVER['SERVER_ADDR'];}else{$ip = @gethostbyname($_SERVER['SERVER_NAME']);}
        if($sysInfo['win_n'] != ''){$serverTag =  $sysInfo['win_n'];}else{$serverTag = @php_uname();};
        $os = explode(" ", php_uname());
        $serverOS = $os[0];
        if('/'==DIRECTORY_SEPARATOR){$core = $os[2];}else{$core = $os[1];}
        $lan = getenv("HTTP_ACCEPT_LANGUAGE");
        if('/'==DIRECTORY_SEPARATOR ){$zhuji = $os[1];}else{$zhuji = $os[2];}
        return [
            'domain'    =>  $serverName,
            'ip'        =>  $ip,
            'serverTag' =>  $serverTag,
            'serverOS'  =>  $serverOS,
            'core'      =>  $core,
            'lan'       =>  $lan,
            'zhuji'     =>  $zhuji
        ];
    }

    /**
     * 获取服务器实时数据
     * @return array
     */
    public function getRealData(){
        $sysInfo = $this->sys_linux();
        $nowDate = date("Y-n-j H:i:s");
        $uptime  = $sysInfo['uptime'];
        $totalDisk = round(@disk_total_space(".")/(1024*1024*1024),3);
        $freeDisk  = round(@disk_free_space(".")/(1024*1024*1024),3);
        $cpuNum  = $sysInfo['cpu']['num'];
        $cpuInfo = $sysInfo['cpu']['model'];
        $tmp = array(
            'memTotal', 'memUsed', 'memFree', 'memPercent',
            'memCached', 'memRealPercent',
            'swapTotal', 'swapUsed', 'swapFree', 'swapPercent'
        );
        foreach ($tmp AS $v) {
            $sysInfo[$v] = $sysInfo[$v] ? $sysInfo[$v] : 0;
        }
        //判断内存如果小于1GB，就显示M，否则显示GB单位
        if($sysInfo['memTotal']<1024)
        {
            $memTotal = $sysInfo['memTotal']." MB";
            $mu = $sysInfo['memUsed']." MB";
            $mf = $sysInfo['memFree']." MB";
            $mc = $sysInfo['memCached']." MB";	//cache化内存
            $mb = $sysInfo['memBuffers']." MB";	//缓冲
            $st = $sysInfo['swapTotal']." MB";
            $su = $sysInfo['swapUsed']." MB";
            $sf = $sysInfo['swapFree']." MB";
            $swapPercent = $sysInfo['swapPercent'];
            $memRealUsed = $sysInfo['memRealUsed']." MB"; //真实内存使用
            $memRealFree = $sysInfo['memRealFree']." MB"; //真实内存空闲
            $memRealPercent = $sysInfo['memRealPercent']; //真实内存使用比率
            $memPercent = $sysInfo['memPercent']; //内存总使用率
            $memCachedPercent = $sysInfo['memCachedPercent']; //cache内存使用率
        }
        else
        {
            $memTotal = round($sysInfo['memTotal']/1024,3)." GB";
            $mu = round($sysInfo['memUsed']/1024,3)." GB";
            $mf = round($sysInfo['memFree']/1024,3)." GB";
            $mc = round($sysInfo['memCached']/1024,3)." GB";
            $mb = round($sysInfo['memBuffers']/1024,3)." GB";
            $st = round($sysInfo['swapTotal']/1024,3)." GB";
            $su = round($sysInfo['swapUsed']/1024,3)." GB";
            $sf = round($sysInfo['swapFree']/1024,3)." GB";
            $swapPercent = $sysInfo['swapPercent'];
            $memRealUsed = round($sysInfo['memRealUsed']/1024,3)." GB"; //真实内存使用
            $memRealFree = round($sysInfo['memRealFree']/1024,3)." GB"; //真实内存空闲
            $memRealPercent = $sysInfo['memRealPercent']; //真实内存使用比率
            $memPercent = $sysInfo['memPercent']; //内存总使用率
            $memCachedPercent = $sysInfo['memCachedPercent']; //cache内存使用率
        }

        $systemLoad = $sysInfo['loadAvg'];

        //返回服务器实时数据
        return [
            'nowDate'   =>  $nowDate,
            'upTime'    =>  $uptime,
            'totalDisk' =>  $totalDisk,
            'freeDiks'  =>  $freeDisk,
            'cpuNum'    =>  $cpuNum,
            'cpuInfo'   =>  $cpuInfo,
            'memUse'    =>  [
                'physic'    =>  [
                    'memTotal'  =>  $memTotal,
                    'mu'        =>  $mu,
                    'mf'        =>  $mf,
                    'memPercent'=>  $memPercent
                ],
                'cache'     =>  [
                    'mc'        =>  $mc,
                    'memCachedPercent'=> $memCachedPercent,
                    'mb'        =>  $mb
                ],
                'real'      =>  [
                    'memRealUsed'   =>  $memRealUsed,
                    'memRealFree'   =>  $memRealFree,
                    'memRealPercent'=>  $memRealPercent
                ],
                'swap'      =>  [
                    'st'    =>  $st,
                    'su'    =>  $su,
                    'sf'    =>  $sf,
                    'swapPercent'   =>  $swapPercent
                ]
            ],
            'load'  =>  $systemLoad
        ];

    }

    /**
     * 获取 网络使用情况
     * @return array
     */
    public function getNetInfo(){
        //网络使用情况
        //网卡流量
        $strs = @file("/proc/net/dev");

        for ($i = 2; $i < count($strs); $i++ )
        {
            preg_match_all( "/([^\s]+):[\s]{0,}(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/", $strs[$i], $info );
            /*	$NetInput[$i] = formatsize($info[2][0]);
                $NetOut[$i]  = formatsize($info[10][0]);
            */
            $tmo = round($info[2][0]/1024/1024, 5);
            $tmo2 = round($tmo / 1024, 5);
            $NetInput[$i] = $tmo2;
            $tmp = round($info[10][0]/1024/1024, 5);
            $tmp2 = round($tmp / 1024, 5);
            $NetOut[$i] = $tmp2;

        }

        $netArr = [];
        if (false !== ($strs = @file("/proc/net/dev"))) {
            for ($i = 2; $i < count($strs); $i++ ){
                preg_match_all( "/([^\s]+):[\s]{0,}(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/", $strs[$i], $info );
                array_push($netArr,[
                    'name'  =>  $info[1][0],
                    'receive'   => $NetInput[$i],
                    'send'      => $NetOut[$i]
                ]);
            }
        }

        return $netArr;
    }

}

$test = new ServerInfoTrans();
$test->getOnlineInfo();